package com.zjmzxfzhl.modules.purchase.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zjmzxfzhl.common.base.BaseServiceImpl;
import com.zjmzxfzhl.common.exception.AppException;
import com.zjmzxfzhl.common.util.FileUtil;
import com.zjmzxfzhl.common.util.PathUtil;
import com.zjmzxfzhl.common.util.bs.PurchaseUtils;
import com.zjmzxfzhl.modules.purchase.controller.dto.PurchaseOrderDetailDto;
import com.zjmzxfzhl.modules.purchase.controller.vo.PurchaseOrderDetailVo;
import com.zjmzxfzhl.modules.purchase.entity.PurchaseOrderDetail;
import com.zjmzxfzhl.modules.purchase.mapper.PurchaseOrderDetailMapper;
import com.zjmzxfzhl.modules.purchase.service.PurchaseOrderDetailService;
import com.zjmzxfzhl.modules.purchase.service.PurchasePaymentService;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Service
 *
 * @author yangjf
 */
@Service
public class PurchaseOrderDetailServiceImpl extends BaseServiceImpl<PurchaseOrderDetailMapper, PurchaseOrderDetail>
        implements PurchaseOrderDetailService {

    @Autowired
    private PurchasePaymentService paymentService;

    @Override
    public IPage<PurchaseOrderDetail> list(IPage<PurchaseOrderDetail> page, PurchaseOrderDetail purchaseOrderDetail) {
        return page.setRecords(baseMapper.list(page, purchaseOrderDetail));
    }

    @Override
    public List<PurchaseOrderDetailVo> listSimpleVoBy(PurchaseOrderDetailDto dto) {
        return this.baseMapper.listDetailBy(dto);
    }


    @Override
    public List<PurchaseOrderDetailVo> listBy(PurchaseOrderDetailDto dto) {
        List<PurchaseOrderDetailVo> detailVos = this.baseMapper.listDetailBy(dto);
        if (!CollectionUtils.isEmpty(detailVos)) {
            Set<Long> contractIdSet = new HashSet<>();
            for (PurchaseOrderDetailVo detailVo : detailVos) {
                if (detailVo.getUnitPrice() != null && detailVo.getMaterialNum() != null) {
                    detailVo.setMaterialTotalPrice(detailVo.getUnitPrice().multiply(detailVo.getMaterialNum()));
                }
                if (null != detailVo.getContractId()) {
                    contractIdSet.add(detailVo.getContractId());
                }
            }

            Map<Long, String> situationMap = new HashMap<>(contractIdSet.size());
            for (Long contractId : contractIdSet) {
                String paymentSituation = paymentService.mergePaymentSituation(contractId);
                situationMap.put(contractId, paymentSituation);
            }
            Map<String, BigDecimal> contractSubAmountMap = new HashMap<>(detailVos.size());
            for (PurchaseOrderDetailVo detailVo : detailVos) {
                if (detailVo.getOrderId() != null && detailVo.getContractId() != null && detailVo.getMaterialTotalPrice() != null) {
                    String key = detailVo.getOrderId() + "|" + detailVo.getContractId();
                    if (contractSubAmountMap.containsKey(key)) {
                        BigDecimal subAmount = detailVo.getMaterialTotalPrice().add(contractSubAmountMap.get(key));
                        contractSubAmountMap.put(key, subAmount);
                    } else {
                        contractSubAmountMap.put(key, detailVo.getMaterialTotalPrice());
                    }
                }
            }
            for (PurchaseOrderDetailVo detailVo : detailVos) {
                if (null != detailVo.getContractId()) {
                    if (detailVo.getOrderId() != null) {
                        String key = detailVo.getOrderId() + "|" + detailVo.getContractId();
                        if (contractSubAmountMap.containsKey(key)) {
                            detailVo.setContractSubAmount(contractSubAmountMap.get(key));
                        }
                    }
                    detailVo.setPaymentSituation(situationMap.get(detailVo.getContractId()));
                }
            }
        }
        return detailVos;
    }

    @Override
    public void deleteByOrderId(Long orderId) {
        this.baseMapper.deleteByOrderId(orderId);
    }

    @Override
    public Integer countByMaterialId(Long materialId) {
        PurchaseOrderDetail filter = new PurchaseOrderDetail();
        filter.setMaterialId(materialId);
        return this.baseMapper.selectCount(new QueryWrapper<>(filter));
    }

    @Override
    public List<PurchaseOrderDetail> listMaterialNotInOrder(Long materialId, Long orderId) {
        return this.baseMapper.listMaterialNotInOrder(materialId, orderId);
    }

    @Override
    public File export(PurchaseOrderDetailDto detailDto) {
        //查询所有相关内容
        detailDto.setOrderByOrderCode(true);
        List<PurchaseOrderDetailVo> orderDetails = this.listBy(detailDto);
        List<Map<String, Object>> excelBos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orderDetails)) {
            for (PurchaseOrderDetailVo detailVo : orderDetails) {
                //将付款情况的换行改成 ";"分隔
                if (!StringUtils.isEmpty(detailVo.getPaymentSituation())) {
                    detailVo.setPaymentSituation(detailVo.getPaymentSituation().replace("\n", ";"));
                }
                excelBos.add(BeanUtil.beanToMap(detailVo));
            }
        }
        File exportFile = null;
        try {
            ClassPathResource templateFileResource = new ClassPathResource("templates/order-detail-template.xls");
            exportFile = PathUtil.getTempFile("设备审批单详情.xls");
            FileUtils.copyInputStreamToFile(templateFileResource.getInputStream(), exportFile);
            PurchaseUtils.exportPurchaseOrderDetail(excelBos, exportFile);
        } catch (Exception e) {
            throw new AppException("文件读取失败" + e.getMessage());
        }
        return exportFile;
    }
}
